home *** CD-ROM | disk | FTP | other *** search
- /*
- File: DocWindow.cp
-
- Contains: A simple document window
-
- Written by: Dave Falkenburg
-
- Copyright: Copyright © 1993-1999 by Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
- 8/19/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1
- 9/27/94 DRF Changes for Dave Mark: AppLib.h is now Sprocket.h.
- 9/9/94 DRF Reordered headers and removed redundant #includes.
- 9/4/94 DRF Added scroll bars and revised dragging methods.
-
- */
-
- #include "Sprocket.h"
- #include "DocWindow.h"
-
- #include <LowMem.h> // for LMGetCurApName()
- #include <ToolUtils.h> // for NumToString()
- #include <Icons.h> // for PlotIconID
- #include <TextUtils.h>
-
-
- unsigned long TDocWindow::fgUntitledTagCount = 0;
-
- const short kHeaderHeight = 20;
-
- const short kFirstSpinningArrowIconID = 801;
- const short kLastSpinningArrowIconID = 808;
-
- const short kDocWindowTemplateID = 1026;
-
-
-
- static pascal void DocWindowControlActionProc(ControlHandle theControl,short partCode);
- static void SpinDocWindowArrows(TDocWindow * windowToSpin);
-
-
- // Functions which are called from external scope, but in turn invoke
- // DocWindow methods. These really could be moved to "Window.h"
-
- static ControlActionUPP
- DocWindowControlAction = NewControlActionProc(DocWindowControlActionProc);
-
- static pascal void
- DocWindowControlActionProc(ControlHandle theControl,short partCode)
- {
- TDocWindow * aDocWindow = NULL;
-
- aDocWindow = (TDocWindow *) GetControlReference(theControl);
-
- if (aDocWindow)
- aDocWindow->DoControlAction(theControl,partCode);
- }
-
-
- static void
- SpinDocWindowArrows(TDocWindow * windowToSpin)
- {
- while (1)
- {
- windowToSpin->SpinHeaderArrows();
- YieldToAnyThread();
- }
- }
-
-
-
- // methods
-
- TDocWindow::TDocWindow()
- {
- OSErr err;
-
- fCurrentSpinningArrowIconID = kFirstSpinningArrowIconID;
- fVerticalScrollActive = fHorizontalScrollActive = false;
-
- fCanAcceptDrag = false;
- fDragTargetRgn = NULL;
-
- TDocWindow::fgUntitledTagCount++; // Starts out as zero but we want “Untitled-1”
- this->CreateWindow();
-
- if (gHasThreadManager)
- {
- err = NewThread(kCooperativeThread,(ThreadEntryProcPtr) SpinDocWindowArrows,this,0,0,nil,&fSpinnerThreadID);
- if (err != noErr)
- DebugStr((StringPtr) "\pNewThread failed");
- }
- }
-
- TDocWindow::~TDocWindow()
- {
- OSErr err;
-
- // NEWS OF THE WEIRD!
- // If you pass true for recyleThread param, the heap block for the stack isn’t
- // disposed— it gets placed in the default cooperative thread pool of “premade”
- // threads.
- //
- // To optimize memory usage, I might just want to go ahead and create
- // a thread pool at application startup so we can avoid moving memory around
- // so much.
-
- if (gHasThreadManager)
- {
- err = DisposeThread(fSpinnerThreadID,nil,false);
- if (err != noErr)
- DebugStr((StringPtr) "\pDisposeThread failed");
- }
- }
-
-
- WindowPtr
- TDocWindow::MakeNewWindow(WindowPtr behindWindow)
- {
- WindowPtr aWindow = GetNewColorOrBlackAndWhiteWindow(kDocWindowTemplateID,nil,behindWindow);
- Str255 titleString;
- GrafPtr savedPort;
- Rect scrollRect;
-
- GetPort(&savedPort);
- if (aWindow)
- {
- // make the window exciting & different
-
- // Can’t call nudge because it assumes the window is visible!
-
- // Nudge(fgUntitledTagCount * kHeaderHeight,fgUntitledTagCount * kHeaderHeight);
-
- GetWTitle(aWindow,titleString);
- if (StrLength(titleString) != 0)
- {
- Str255 numberString;
-
- NumToString(fgUntitledTagCount,numberString);
- BlockMove(&numberString[1],&titleString[titleString[0]+1],numberString[0]);
- titleString[0] += numberString[0];
- }
- SetWTitle(aWindow,titleString);
-
- SetPort(aWindow);
-
- // create vertical scroll bar
- scrollRect.top = aWindow->portRect.top + kHeaderHeight -1;
- scrollRect.left = aWindow->portRect.right - kScrollbarWidth + 1;
- scrollRect.bottom = aWindow->portRect.bottom - kScrollbarWidth + kScrollbarTweak;
- scrollRect.right = aWindow->portRect.right + 1;
-
- fVerticalScroll = NewControl(aWindow,&scrollRect,"\p", true,/* value = */ 0 ,/* min = */ 0, /* max = */ 255, scrollBarProc, (long) this);
- SetControlAction(fVerticalScroll,DocWindowControlAction);
-
- // create horizontal scroll bar
- scrollRect.top = aWindow->portRect.bottom - kScrollbarWidth + 1;
- scrollRect.left = aWindow->portRect.left -1;
- scrollRect.bottom = aWindow->portRect.bottom + 1;
- scrollRect.right = aWindow->portRect.right - kScrollbarWidth + kScrollbarTweak;
- fHorizontalScroll = NewControl(aWindow,&scrollRect,"\p", true,/* value = */ 0 ,/* min = */ 0, /* max = */ 255, scrollBarProc, (long) this);
- SetControlAction(fHorizontalScroll,DocWindowControlAction);
-
- ShowWindow(aWindow);
- }
- SetPort(savedPort);
-
- return aWindow;
- }
-
-
- void
- TDocWindow::Activate(Boolean activating)
- {
- short verticalHiliteValue,horizontalHiliteValue;
-
- if (activating)
- {
- verticalHiliteValue = (fVerticalScrollActive ? 0 : 255);
- horizontalHiliteValue = (fHorizontalScrollActive ? 0 : 255);
- }
- else
- {
- verticalHiliteValue = horizontalHiliteValue = 254;
- }
-
- HiliteControl(fVerticalScroll,verticalHiliteValue);
- HiliteControl(fHorizontalScroll,horizontalHiliteValue);
-
- DrawJustTheGrowIcon(fWindow);
- }
-
-
- void
- TDocWindow::AdjustCursor(EventRecord * /* anEvent */)
- {
- }
-
-
- void
- TDocWindow::Draw(void)
- {
- EraseRect(&fWindow->portRect);
-
- MoveTo(0,kHeaderHeight-3); LineTo(fWindow->portRect.right,kHeaderHeight-3);
- MoveTo(0,kHeaderHeight-1); LineTo(fWindow->portRect.right,kHeaderHeight-1);
-
- UpdateControls(fWindow,fWindow->visRgn);
-
- DrawJustTheGrowIcon(fWindow);
- }
-
-
- void
- TDocWindow::Click(EventRecord * anEvent)
- {
- ControlHandle theControl = NULL;
- short theControlPartCode;
-
- theControlPartCode = FindControl(anEvent->where,fWindow,&theControl);
-
- if (theControl != NULL)
- {
- // NOTE: NON-NULL action procs don’t work for scrollbar thumbs!
- if (theControlPartCode != kControlIndicatorPart)
- (void) TrackControl(theControl,anEvent->where,DocWindowControlAction);
- else
- {
- // You might ask: What the heck is CW doing to make this work???
- // They don’t call TrackControl, instead they roll their own
- // using TestControl & SetControlValue. This is left as an
- // excercise to the reader, and we do the OLD HI method of
- // dragging a ghost thumb around
-
- (void) TrackControl(theControl,anEvent->where,NULL);
- }
- }
- else
- {
- if (MyFrontNonFloatingWindow() != fWindow)
- {
- this->Select();
- }
- else
- {
- }
- }
- }
-
-
- void
- TDocWindow::AdjustForNewWindowSize(Rect *oldSize,Rect * newSize)
- {
- Rect growBoxRect;
-
- // Invalidate the old grow box
- growBoxRect.top = oldSize->bottom - kScrollbarWidth;
- growBoxRect.bottom = oldSize->bottom;
- growBoxRect.left = oldSize->right - kScrollbarWidth;
- growBoxRect.right = oldSize->right;
- InvalRect(&growBoxRect);
-
- // HideControl does an InvalRect for us, and hides all the jerky control movement from the user.
- HideControl(fVerticalScroll);
- HideControl(fHorizontalScroll);
-
- MoveControl(fVerticalScroll,newSize->right - kScrollbarWidth + 1,newSize->top + kHeaderHeight-1);
- MoveControl(fHorizontalScroll,newSize->left - 1,newSize->bottom - kScrollbarWidth + 1);
-
- SizeControl(fVerticalScroll,kScrollbarWidth,(newSize->bottom - newSize->top) - kHeaderHeight + 1 - kScrollbarWidth + kScrollbarTweak);
- SizeControl(fHorizontalScroll,(newSize->right - newSize->left + 1) - kScrollbarWidth + kScrollbarTweak,kScrollbarWidth);
-
- // Now that we’ve moved & resized the scroll bars, show them.
- ShowControl(fVerticalScroll);
- ShowControl(fHorizontalScroll);
-
- DrawJustTheGrowIcon(fWindow);
- }
-
-
- Boolean
- TDocWindow::Close(void)
- {
- StandardCloseResult result;
- Str255 title;
-
- GetWTitle(this->fWindow,title);
- result = StandardCloseDocument(LMGetCurApName(),title,false,false);
-
- if (result != kCancelSaveDocument)
- {
- return TWindow::Close();
- }
- return false;
- }
-
-
- OSErr
- TDocWindow::DragEnterWindow(DragReference theDrag)
- {
- // preflight to determine if we can accept any of the drag
-
- fCanAcceptDrag = true; // accept anything for now
-
- fDragTargetRgn = NewRgn();
- SetRectRgn( fDragTargetRgn,
- fWindow->portRect.left,
- fWindow->portRect.top + kHeaderHeight,
- fWindow->portRect.right-kScrollbarWidth+1,
- fWindow->portRect.bottom-kScrollbarWidth+1);
-
- return this->DragInWindow(theDrag);
- }
-
-
- OSErr
- TDocWindow::DragInWindow(DragReference theDrag)
- {
- if (fCanAcceptDrag)
- {
- Point mouseLoc, pinnedMouseLoc;
-
- (void) GetDragMouse(theDrag,&mouseLoc,&pinnedMouseLoc);
- GlobalToLocal(&mouseLoc);
-
- if (PtInRgn(mouseLoc,fDragTargetRgn))
- ShowDragHilite(theDrag,fDragTargetRgn,true);
- else
- HideDragHilite(theDrag);
- }
-
- return noErr;
- }
-
-
- OSErr
- TDocWindow::DragLeaveWindow(DragReference theDrag)
- {
- fCanAcceptDrag = false;
- DisposeRgn(fDragTargetRgn);
- HideDragHilite(theDrag);
- return noErr;
- }
-
-
- OSErr
- TDocWindow::HandleDrop(DragReference /* theDrag */)
- {
- return noErr;
- }
-
-
- void
- TDocWindow::DoControlAction(ControlHandle whichControl,short /* whichPart */)
- {
- if (whichControl == fVerticalScroll)
- {
- }
- else if (whichControl == fHorizontalScroll)
- {
- }
- }
-
-
- void
- TDocWindow::SpinHeaderArrows()
- {
- GrafPtr oldPort;
-
- GetPort(&oldPort);
- SetPort(fWindow);
-
- Rect r;
-
- fCurrentSpinningArrowIconID++;
-
- if (fCurrentSpinningArrowIconID > kLastSpinningArrowIconID)
- fCurrentSpinningArrowIconID = kFirstSpinningArrowIconID;
-
- r.top = fWindow->portRect.top;
- r.left = fWindow->portRect.left+4;
- r.bottom = r.top + 16;
- r.right = r.left + 16;
- (void) PlotIconID(&r,atNone,ttNone,fCurrentSpinningArrowIconID);
-
- SetPort(oldPort);
- }
-